package com.jf.cloud.common.serializer;

import cn.hutool.core.collection.CollectionUtil;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.jf.cloud.common.constant.Auth;
import com.jf.cloud.common.feign.FeignInsideAuthConfig;
import com.jf.cloud.common.handler.SensitiveHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashSet;
import java.util.Objects;

/**
 * @author zz
 */
@Component
public class SensitiveJsonSerializer extends JsonSerializer<Object> {

    private static final Logger logger = LoggerFactory.getLogger(SensitiveJsonSerializer.class);

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private SensitiveHandler sensitiveHandler;

    private static final String MENU_PERMISSION_USER_LIST = "/mp/menu_permission/list";
    private static final String MENU_PERMISSION_USER_PAGE = "/mp/menu_permission/page";
    private static final String SENSITIVE_WORD_SEARCH_URL = "/p/sys_config/info/SENSITIVE_WORDS";
    private static final String FEIGN_URL = FeignInsideAuthConfig.FEIGN_URL_PREFIX + "/**";
    private static final String SENSITIVE_WORD_CONFIG_URL = FeignInsideAuthConfig.FEIGN_URL_PREFIX + "/insider/config/getConfig";
    private static final String GET_CAPTCHA = "/ua/captcha/get";
    private static final String CHECK_CAPTCHA = "/ua/captcha/check";

    static final HashSet<String> SENSITIVE_WHITE_SET;
    static {
        SENSITIVE_WHITE_SET = new HashSet<>();
        SENSITIVE_WHITE_SET.add(Auth.CHECK_TOKEN_URI);
        SENSITIVE_WHITE_SET.add(Auth.CHECK_RBAC_URI);
        SENSITIVE_WHITE_SET.add(SENSITIVE_WORD_CONFIG_URL);
        SENSITIVE_WHITE_SET.add(SENSITIVE_WORD_SEARCH_URL);
        SENSITIVE_WHITE_SET.add(GET_CAPTCHA);
        SENSITIVE_WHITE_SET.add(CHECK_CAPTCHA);
        SENSITIVE_WHITE_SET.add(MENU_PERMISSION_USER_LIST);
        SENSITIVE_WHITE_SET.add(MENU_PERMISSION_USER_PAGE);
        SENSITIVE_WHITE_SET.add(FEIGN_URL);
    }


    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (Objects.isNull(requestAttributes)) {
            gen.writeObject(value);
            return;
        }
        HttpServletRequest request = requestAttributes.getRequest();

        AntPathMatcher antPathMatcher = new AntPathMatcher();
        if (CollectionUtil.isNotEmpty(SENSITIVE_WHITE_SET)) {
            for (String sensitiveUrl : SENSITIVE_WHITE_SET) {
                if (antPathMatcher.match(sensitiveUrl, request.getRequestURI())) {
                    gen.writeObject(value);
                    return;
                }
            }
        }
        if (Objects.isNull(value)) {
            return;
        }
        try {
            String jsonData = objectMapper.writeValueAsString(value);
            String sensitiveText = sensitiveHandler.replaceSensitiveWord(jsonData, SensitiveHandler.minMatchType, "*");

            gen.writeObject(objectMapper.readValue(sensitiveText,value.getClass()));
        } catch (Exception e) {
            logger.error("敏感词替换错误：", e);
        }
    }
}
